package com.example.demo.redis;

import com.example.demo.annotation.Log;
import com.example.demo.mybatisPlus.entity.Dict;
import com.example.demo.mybatisPlus.service.DictService;
import com.example.demo.utils.bean.BeanUtils;
import com.example.demo.utils.common.StringUtils;
import com.example.demo.utils.json.JSONUtils;
import lombok.AllArgsConstructor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;

@RestController
@AllArgsConstructor
public class RedisController {

    private static Logger logger = LoggerFactory.getLogger(RedisController.class);

    /** 操作数据库 */
    private DictService dictService;
    /** redis */
    private RedisUtils redisUtils;

    /**
     * 缓存注解的使用
     * Cacheable：调用方法时先从缓存中查询有没有对应key的数据，如果有直接从缓存获取返回，如果没有则执行方法，将返回值存入缓存中。
     *          unless 不执行Cacheable的条件（设置如果查询的结果为空时，不存储至缓存）   condition 参数就是执行Cacheable的条件
     * CacheEvict：调用方法后从缓存中删除对应key的数据
     * Caching：当一个方法需要查询多个缓存或者删除多个缓存时使用
     */
    @GetMapping("/redis/{id}")
    @Cacheable(value = "common", key = "#id", unless = "#result == null")
    @Log(title = "测试redis数据读取")
    public Dict testRedis(@PathVariable Long id) {
        /** redis基础存储 */
//        testRedisBaseSave();
        /** redis数据判断 */
        return testRedisData(id);
    }

    /** redis基础存储 */
    private void testRedisBaseSave() {
        /** MyBatis获取第一页20条数据 */
//        List<Dict> list = dictService.selectDictPage(new Page(1, 20), new Dict());
        /** MyBatis-Plus 获取所有数据 */
//        List<Dict> list = dictService.selectList(new QueryWrapper<>());
        /** list数据存储 */
//        if (redisUtils.lSet("dictList", list)) return "success";
        /** map数据存储 */
//        list.forEach(data-> {
//            Map<String, Object> map = new HashMap<>();
//            map.put(data.getId().toString(), data);
//            redisUtils.hmset(data.getId().toString(), map);
//        });
        /** redis删除指定键值 */
//        redisUtils.del("dictList");
    }

    /** redis数据判断 */
    private Dict testRedisData(Long id) {
        /** 当数据在缓存中存在时，直接获取返回，否则查询数据库 */
        Object object = redisUtils.get(id.toString());
        Dict dict;
        if (StringUtils.isNull(object)) {
            /** 缓存中不存在，从数据库中获取 */
            logger.debug("缓存中不存在，从数据库中获取");
            dict = dictService.getById(id);
            if (StringUtils.isNull(dict)) {
                logger.debug("数据库不存在");
            } else {
                logger.debug(JSONUtils.toJSONObject(dict).toJSONString());
                if (redisUtils.set(id.toString(), dict)) logger.debug("加入redis缓存成功");
            }
        } else {
            logger.debug("缓存存在，直接返回");
            /** 缓存存在，直接返回 */
            dict = new Dict();
            BeanUtils.copyProperties(object, dict);
            logger.debug(JSONUtils.toJSONObject(dict).toJSONString());
        }
        return dict;
    }

}
